package org.ala.tiktools.tools;

import java.util.function.BiConsumer;

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.ApplicationContext;

/**
 * Bean工具
 *
 * @author ala
 * @date 2025-04-05 22:59
 */
public class BeanTools {


    /**
     *  根据class拿bean
     */
    public static <T> T getBean(ApplicationContext context, Class<T> clazz) {
        return context.getBean(clazz);
    }
    
    /**
     *  根据class拿bean
     */
    public static <T> T getBean(ApplicationContext context, String beanName, Class<T> clazz) {
        return context.getBean(beanName, clazz);
    }

    /**
     *  根据class拿bean，如果拿不到或拿到了多个，则new一个
     */
    public static <T> T getBeanOrNew(ApplicationContext context, Class<T> clazz) {
        try {
            return context.getBean(clazz);
        } catch (Exception e) {
            return ReflectionTools.newInstance(clazz);
        }
    }


    /**
     *  注册BeanDefined
     */
    public static void registerBeanDefined(BeanDefinitionRegistry registry, String beanName, Class<?> clazz, BiConsumer<BeanDefinitionBuilder, AbstractBeanDefinition> consumer) {
        BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(clazz);
        builder.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
        
        //	生成beanDefintion
        AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
        beanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON);
        beanDefinition.setPrimary(true);
        
        if (consumer != null) { consumer.accept(builder, beanDefinition); }
        
        //	注册
        BeanDefinitionHolder holder = new BeanDefinitionHolder(beanDefinition, beanName);
        BeanDefinitionReaderUtils.registerBeanDefinition(holder, registry);
    }
    /**
     *  注册已经实例化好的bean
     */
    public static void registerBeanDefined(BeanDefinitionRegistry registry, String beanName, Object bean, BiConsumer<BeanDefinitionBuilder, AbstractBeanDefinition> consumer) {
        BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(bean.getClass());
        builder.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);

        //	生成beanDefintion
        AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
        beanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON);
        beanDefinition.setPrimary(true);
        //	直接给已经实例化出来的对象（生命周期我自己管，spring你别瞎操心了）
        beanDefinition.setInstanceSupplier(() -> bean);
        
        if (consumer != null) { consumer.accept(builder, beanDefinition); }

        //	注册
        BeanDefinitionHolder holder = new BeanDefinitionHolder(beanDefinition, beanName);
        BeanDefinitionReaderUtils.registerBeanDefinition(holder, registry);
    }
}
